package com.xlf.service.ai.service;


import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.xlf.common.core.exception.BizException;
import com.xlf.common.core.util.StringUtils;
import com.xlf.service.ai.common.ConvertUtils;
import com.xlf.service.ai.common.MessageUtils;
import com.xlf.service.ai.pojo.dto.ChatBaseRequest;
import com.xlf.service.ai.pojo.dto.ChatResponse;
import com.xlf.service.ai.pojo.dto.Message;
import com.xlf.service.ai.utils.JacksonUtils;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;


@Slf4j
public abstract class BaseClient implements SingleBot, ContBot ,BaseBot {


    /**
     * 多播持久化容器，单播不会保存纪录
     */
    private MessagesContainer messagesContainer;

    public void setMessagesContainer(MessagesContainer messagesContainer) {
        this.messagesContainer = messagesContainer;
    }

    public MessagesContainer getMessagesContainer() {
        return messagesContainer;
    }


    @Override
    public ChatResponse chatSingle(String content) {
        return chatSingle(buildRequest(content));
    }

    @Override
    public <T extends ChatBaseRequest> ChatResponse chatSingle(T chatRequest) {
        return chatCont(chatRequest,null);
    }

    @Override
    public ChatResponse chatCont(String content, String msgUid) {
        return chatCont(buildRequest(content),msgUid);
    }

    @Override
    public <T extends ChatBaseRequest> ChatResponse chatCont(T chatRequest, String msgUid) {

        //获取历史纪录
        List<Message> messagesHistory = new ArrayList<>();

        //msgUid不为空为多播
        if(StringUtils.isNotEmpty(msgUid))
            messagesHistory = messagesContainer.getMessagesHistory(msgUid);

        ArrayList<Message> messages = new ArrayList<>(messagesHistory);
        //封装请求体
        String requestBody = ConvertUtils.buildTargetRequestBody(messages, false, chatRequest);

        log.info(msgUid + "：请求模型:"  + getTag() + "---请求体：" + requestBody);
        //发送请求
        String body = HttpRequest.post(getURL() + "?access_token=" + getCustomAccessToken())
                .body(requestBody)
                .header("Content-Type", "application/json")
                .execute().body();
        ChatResponse chatResponse = JacksonUtils.toObj(body, ChatResponse.class);

        String errorMsg = chatResponse.getErrorMsg();

        if(StringUtils.isNotEmpty(errorMsg) ||
                StringUtils.isNotNull(chatResponse.getErrorCode()) ||
                StringUtils.isNotNull(chatResponse.getEbCode())){
            log.error(msgUid + "：响应模型:"  + getTag() + "失败---响应体：" + body);
            throw new BizException("系统错误，联系管理员处理");
        }
        log.info(msgUid + "：响应模型:"  + getTag() + "成功---响应体：" + body);

        if(StringUtils.isNotEmpty(msgUid)){
            messagesContainer.addMessagesHistory(MessageUtils.buildUserMessage(chatRequest.getContent()),msgUid);
            messagesContainer.addMessagesHistory(MessageUtils.buildAssistantMessage(chatResponse.getResult()),msgUid);
        }

        return chatResponse;
    }



    @Override
    public <T extends ChatBaseRequest> void chatSingleOfStream(String content, Consumer<ChatResponse> subscription) {
         chatSingleOfStream(buildRequest(content),subscription);
    }

    @Override
    public <T extends ChatBaseRequest> void chatSingleOfStream(T chatRequest, Consumer<ChatResponse> subscription) {
        chatContOfStream(chatRequest,null,subscription);
    }


    @Override
    public <T extends ChatBaseRequest> void chatContOfStream(String content, String msgUid, Consumer<ChatResponse> subscription) {
        chatContOfStream(buildRequest(content),msgUid,subscription);
    }

    @Override
    public <T extends ChatBaseRequest> void chatContOfStream(T chatRequest, String msgUid, Consumer<ChatResponse> subscription) {

        //获取历史纪录
        List<Message> messagesHistory = new ArrayList<>();

        //msgUid不为空为多播
        if(StringUtils.isNotEmpty(msgUid))
            messagesHistory = messagesContainer.getMessagesHistory(msgUid);

        ArrayList<Message> messages = new ArrayList<>(messagesHistory);
        //封装请求体
        String requestBody = ConvertUtils.buildTargetRequestBody(messages, true, chatRequest);
        log.info(msgUid + "：请求模型:"  + getTag() + "---请求体：" + requestBody);
        //发送请求
        HttpResponse response = HttpRequest.post(getURL() + "?access_token=" + getCustomAccessToken())
                .body(requestBody)
                .header("Content-Type", "application/json")
                .executeAsync();

        InputStream inputStream = response.bodyStream();
        StringBuilder stringBuilder = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
            String data;
            while ((data = reader.readLine()) != null) {
                System.out.println(data);
                if(StringUtils.isEmpty(data) || !data.startsWith("data: "))
                    continue;
                ChatResponse chatResponse = JacksonUtils.toObj(data.substring(6), ChatResponse.class);
                stringBuilder.append(chatResponse.getResult());
                subscription.accept(chatResponse);
                String errorMsg = chatResponse.getErrorMsg();
                if(StringUtils.isNotEmpty(errorMsg) ||
                        StringUtils.isNotNull(chatResponse.getErrorCode()) ||
                        StringUtils.isNotNull(chatResponse.getEbCode())){
                    log.error(msgUid + "：响应模型:"  + getTag() + "失败---响应体：" + data);
                    throw new BizException("系统错误，联系管理员处理");
                }
                if(chatResponse.getIsEnd()){
                    response.close();
                    break;
                }
            }
        } catch (Exception e) {
            log.error("Error reading stream: " + e.getMessage());
        } finally {
            if(response != null)
                response.close();
        }

        if(StringUtils.isNotEmpty(msgUid)){
            messagesContainer.addMessagesHistory(MessageUtils.buildUserMessage(chatRequest.getContent()),msgUid);
            messagesContainer.addMessagesHistory(MessageUtils.buildAssistantMessage(stringBuilder.toString()),msgUid);
        }
        log.info(msgUid + "：响应模型:"  + getTag() + "成功---响应内容：" + stringBuilder.toString());

    }


    public ChatBaseRequest buildRequest(String content) {
        return ChatBaseRequest.builder().content(content).build();
    }

}
